package com.cskaoyan._06clone;

/**
 * @description:
 * @author: 景天
 * @date: 2023/2/14 17:11
 **/
/*
使用clone方法的步骤
1.重写clone方法,修改权限
2.把返回值类型修改成自身类型
3.要求实现clone方法的类,实现Cloneable接口
    Cloneable空接口,起到标记的作用
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User("张三", 20,
                new Address("湖北省武汉市洪山区软件新城C13"));
        User cloneUser = user.clone();
        System.out.println(cloneUser);
        System.out.println(user == cloneUser);
        System.out.println(user.equals(cloneUser));

        System.out.println(user.address == cloneUser.address);
        //user.address.detail = "C8";
        //System.out.println(cloneUser.address.detail);

    }
}

class User implements Cloneable {
    String name;
    int age;
    Address address;

    public User(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        if (name != null ? !name.equals(user.name) : user.name != null) return false;
        return address != null ? address.equals(user.address) : user.address == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        result = 31 * result + (address != null ? address.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }

    //@Override
    //protected User clone() throws CloneNotSupportedException {
    //    return (User) super.clone();
    //}

    // 修改成深拷贝
    @Override
    protected User clone() throws CloneNotSupportedException {
        User cloneUser = (User) super.clone();
        // 在浅拷贝的基础上进行修改
        Address cloneAddress = this.address.clone();
        // 把Address这个引用再clone一份
        // 赋值给克隆出的User对象的address
        cloneUser.address = cloneAddress;
        return cloneUser;
    }
}

class Address implements Cloneable {
    String detail;

    public Address(String detail) {
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "Address{" +
                "detail='" + detail + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Address address = (Address) o;

        return detail != null ? detail.equals(address.detail) : address.detail == null;
    }

    @Override
    public int hashCode() {
        return detail != null ? detail.hashCode() : 0;
    }

    @Override
    public Address clone() throws CloneNotSupportedException {
        return (Address) super.clone();
    }
}